#include "Token.h"

#include <cassert>

C32String CToken::ToString() const
{
    switch (Type)
    {
        case ETokenType::Identifier:
        {
            auto Str=std::get<C32String>(LiteralValue.value());
            return Str;
        }
        case ETokenType::LiteralString:
        {
            auto Str=std::get<C32String>(LiteralValue.value());
            return U'\"'+ Str + U'\"';
        }

        case ETokenType::LiteralNumber:
        {
            auto Value=LiteralValue.value();

            //visit all number type
            std::visit([](auto&& arg) {
                //using T = std::decay_t<decltype(arg)>;
                
                // convert to u32string
                return C32String(arg);
            }, Value);


        }

        case ETokenType::This:
        {
            return U"this";
        }
        case ETokenType::New:
        {
            return U"new";
        }
        case ETokenType::Return:
        {
            return U"return";
        }
        case ETokenType::If:
        {
            return U"if";
        }
        case ETokenType::Else:
        {
            return U"else";
        }
        case ETokenType::For:
        {
            return U"for";
        }
        case ETokenType::While:
        {
            return U"while";
        }
        case ETokenType::Do:
        {
            return U"do";
        }
        case ETokenType::Switch:
        {
            return U"switch";
        }
        case ETokenType::Case:
        {
            return U"case";
        }
        case ETokenType::Default:
        {
            return U"default";
        }
        case ETokenType::Break:
        {
            return U"break";
        }
        case ETokenType::Continue:
        {
            return U"continue";
        }
        case ETokenType::Goto:
        {
            return U"goto";
        }
        case ETokenType::Throw:
        {
            return U"throw";
        }
        case ETokenType::Try:
        {
            return U"try";
        }
        case ETokenType::Catch:
        {
            return U"catch";
        }
        case ETokenType::Finally:
        {
            return U"finally";
        }
        case ETokenType::Namespace:
        {
            return U"namespace";
        }
        case ETokenType::Class:
        {
            return U"class";
        }
        case ETokenType::Struct:
        {
            return U"struct";
        }
        case ETokenType::Interface:
        {
            return U"interface";
        }
        case ETokenType::Enum:
        {
            return U"enum";
        }
        case ETokenType::Operator:
        {
            return U"operator";
        }
        case ETokenType::Extern:
        {
            return U"extern";
        }
        case ETokenType::Static:
        {
            return U"static";
        }
        case ETokenType::Const:
        {
            return U"const";
        }
        case ETokenType::Volatile:
        {
            return U"volatile";
        }
        case ETokenType::Override:
        {
            return U"override";
        }
        case ETokenType::Abstract:
        {
            return U"abstract";
        }
        case ETokenType::Virtual:
        {
            return U"virtual";
        }
        case ETokenType::Explicit:
        {
            return U"explicit";
        }
        case ETokenType::Public:
        {
            return U"public";
        }
        case ETokenType::Private:
        {
            return U"private";
        }
        case ETokenType::Protected:
        {
            return U"protected";
        }
        case ETokenType::Equal:
        {
            return U"==";
        }
        case ETokenType::NotEqual:
        {
            return U"!=";
        }
        case ETokenType::Less:
        {
            return U"<";
        }
        case ETokenType::LessEqual:
        {
            return U"<=";
        }
        case ETokenType::Greater:
        {
            return U">";
        }
        case ETokenType::GreaterEqual:
        {
            return U">=";
        }
        case ETokenType::AndAnd:
        {
            return U"&&";
        }
        case ETokenType::OrOr:
        {
            return U"||";
        }
        case ETokenType::PlusPlus:
        {
            return U"++";
        }
        case ETokenType::MinusMinus:
        {
            return U"--";
        }
        case ETokenType::LeftShift:
        {
            return U"<<";
        }
        case ETokenType::RightShift:
        {
            return U">>";
        }
        case ETokenType::PlusAssign:
        {
            return U"+=";
        }
        case ETokenType::MinusAssign:
        {
            return U"-=";
        }
        case ETokenType::MultiplyAssign:
        {
            return U"*=";
        }
        case ETokenType::DivideAssign:
        {
            return U"/=";
        }
        case ETokenType::ModAssign:
        {
            return U"%=";
        }
        case ETokenType::AndAssign:
        {
            return U"&=";
        }
        case ETokenType::OrAssign:
        {
            return U"|=";
        }
        case ETokenType::XorAssign:
        {
            return U"^=";
        }
        case ETokenType::LeftShiftAssign:
        {
            return U"<<=";
        }
        case ETokenType::RightShiftAssign:
        {
            return U">>=";
        }
        case ETokenType::Question:
        {
            return U"?";
        }
        case ETokenType::Colon:
        {
            return U":";
        }
        case ETokenType::Semicolon:
        {
            return U";";
        }
        case ETokenType::Comma:
        {
            return U",";
        }
        case ETokenType::Dot:
        {
            return U".";
        }
        case ETokenType::Assign:
        {
            return U"=";
        }
        case ETokenType::NotOperator:
        {
            return U"!";
        }
        case ETokenType::Tilde:
        {
            return U"~";
        }
        case ETokenType::Plus:
        {
            return U"+";
        }
        case ETokenType::Minus:
        {
            return U"-";
        }
        case ETokenType::Multiply:
        {
            return U"*";
        }
        case ETokenType::Divide:
        {
            return U"/";
        }
        case ETokenType::Mod:
        {
            return U"%";
        }
        case ETokenType::And:
        {
            return U"&";
        }
        case ETokenType::Or:
        {
            return U"|";
        }
        case ETokenType::Xor:
        {
            return U"^";
        }
        case ETokenType::LeftParentheses:
        {
            return U"(";
        }
        case ETokenType::RightParentheses:
        {
            return U")";
        }
        case ETokenType::LeftBracket:
        {
            return U"[";
        }
        case ETokenType::RightBracket:
        {
            return U"]";
        }
        case ETokenType::LeftBrace:
        {
            return U"{";
        }
        case ETokenType::RightBrace:
        {
            return U"}";
        }
        
        case ETokenType::RCLASS:
        {
            return U"RCLASS";
        }

        case ETokenType::RSTRUCT:
        {
            return U"RSTRUCT";
        }

        case ETokenType::RENUM:
        {
            return U"RENUM";
        }

        case ETokenType::RFIELD:
        {
            return U"RFIELD";
        }

        case ETokenType::RFUNCTION:
        {
            return U"RFUNCTION";
        }



        default:
        {
            assert(false&&"Unimplemented token type");
            return U"";
        }
    }
}
